package main

import (
	"fmt"
	"time"
)

func main() {
	channelSelect()
	deferAndRecover()
}

// channelSelect
//
//	@Description: 使用select解决从管道取数据阻塞的问题
func channelSelect() {
	numChannel := make(chan int, 10)
	for i := 0; i < 10; i++ {
		numChannel <- i
	}

	strChannel := make(chan string, 5)
	for i := 0; i < 5; i++ {
		strChannel <- "hello" + fmt.Sprintf("%d", i)
	}

	//传统的方法在遍历channel时，如果不关闭channel会阻塞而导致deadlock
	//使用select 解决,取不到会到下一个case匹配
	for {
		select {
		case v := <-numChannel:
			fmt.Println("从[numChannel]获取到的数据=", v)
			time.Sleep(time.Millisecond * 100)
		case v := <-strChannel:
			fmt.Println("从[strChannel]获取到的数据=", v)
			time.Sleep(time.Millisecond * 100)
		default:
			fmt.Println("都取不到数据，不玩了")
			//time.Sleep(time.Millisecond * 100)
			return //注意 break无法跳出此处for
		}
	}
}

// deferAndRecover
//
//	@Description: defer+recover
func deferAndRecover() {
	useMap()
	sayHello()
	for i := 0; i < 3; i++ {
		fmt.Println("main() index=", i)
		time.Sleep(time.Millisecond * 100)
	}
}

func useMap() {
	defer func() {
		err := recover()
		if err != nil {
			fmt.Println("err=", err) //err= assignment to entry in nil map
		}
	}()
	var a map[int]string
	a[0] = "tom"
}
func sayHello() {
	fmt.Println("hello")
	fmt.Println("hello")
	fmt.Println("hello")
}
